﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using Microsoft.TeamFoundation.WorkItemTracking.Client;

namespace TFSCodeReviewHelper
{
    /// <summary>
    /// Interaction logic for WorkItemVisualizer.xaml
    /// </summary>
    public partial class WorkItemVisualizer : UserControl
    {
        public WorkItemVisualizer()
        {
            InitializeComponent();
            DataContext = new WorkItemVisualizerPresentation();
        }
    }

    /// <summary>
    /// Presentation class for the WorkItemVisualizer user control.
    /// </summary>
    internal class WorkItemVisualizerPresentation : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string strPropertyName)
        {
            if (null != PropertyChanged)
                PropertyChanged(this, new PropertyChangedEventArgs(strPropertyName));
        }
        #endregion

        #region Work Item Binding Properties

        private string _WorkItemTitle;
        public string WorkItemTitle
        {
            get { return _WorkItemTitle; }
            set
            {
                _WorkItemTitle = value;
                OnPropertyChanged("WorkItemTitle");
            }
        }

        private string _WorkItemNumber;
        public string WorkItemNumber
        {
            get { return _WorkItemNumber; }
            set
            {
                _WorkItemNumber = value;
                OnPropertyChanged("WorkItemNumber");
            }
        }

        private string _AssignedTo;
        public string AssignedTo
        {
            get { return _AssignedTo; }
            set
            {
                _AssignedTo = value;
                OnPropertyChanged("AssignedTo");
            }
        }

        private string _WorkItemState;
        public string WorkItemState
        {
            get { return _WorkItemState; }
            set
            {
                _WorkItemState = value;
                OnPropertyChanged("WorkItemState");
            }
        }

        private string _WorkItemTypeName;
        public string WorkItemTypeName
        {
            get { return _WorkItemTypeName; }
            set
            {
                _WorkItemTypeName = value;
                OnPropertyChanged("WorkItemTypeName");
            }
        }

        #endregion

        /// <summary>
        /// Default constructor
        /// </summary>
        public WorkItemVisualizerPresentation() : this(null)
        {
        }

        /// <summary>
        /// Constructor that takes a work item for initial display of values.
        /// </summary>
        /// <param name="aWorkItem">Work item to get values from.</param>
        public WorkItemVisualizerPresentation(WorkItem aWorkItem)
        {
            AssignValuesFromWorkItem(aWorkItem);
        }

        /// <summary>
        /// From the input, determines values to present to the user.
        /// </summary>
        /// <param name="aWorkItem">The work item, may be null.</param>
        private void AssignValuesFromWorkItem(WorkItem aWorkItem)
        {
            if (null != aWorkItem)
            {
                UseValuesFromWorkItemForPresentation(aWorkItem);
            }
            else
            {
                UseDefaultValuesForWorkItemPresentation();
            }
        }

        /// <summary>
        /// Set properties on the presentation associated with the given work item.
        /// </summary>
        /// <param name="aWorkItem">The work item to display information about.  Cannot be null.</param>
        private void UseValuesFromWorkItemForPresentation(WorkItem aWorkItem)
        {
            WorkItemTitle = aWorkItem.Title;
            WorkItemNumber = aWorkItem.Id.ToString();
            WorkItemState = aWorkItem.State;
            WorkItemTypeName = aWorkItem.Type.Name;

            // The "assigned to" is not a default field so there may not be a value for it.
            AssignedTo = "<Unknown>";
            var assignedTo = GetFieldFromWorkItem(aWorkItem, @"Assigned To");
            if ((null != assignedTo) && (null != assignedTo.Value))
                AssignedTo = assignedTo.Value.ToString();
        }

        /// <summary>
        /// Returns the field from the work item, if it exists.
        /// </summary>
        /// <param name="aWorkItem">WorkItem</param>
        /// <param name="strFieldName">Field to get from the given work item.</param>
        /// <returns>Field object if it exists on the work item, NULL if it doesn't exist.</returns>
        private Field GetFieldFromWorkItem(WorkItem aWorkItem, string strFieldName)
        {
            Field field;
            try
            {
                field = aWorkItem.Fields[strFieldName];
            }
            catch (Exception)
            {
                field = null;
            }
            return field;
        }

        /// <summary>
        /// Writes the contents of the work item to the console output for debugging information.
        /// </summary>
        /// <param name="aWorkItem"></param>
        protected void DumpWorkItemFields(WorkItem aWorkItem)
        {
            foreach (Field aField in aWorkItem.Fields)
            {
                if (null != aField)
                {
                    if (null != aField.Value)
                        Console.WriteLine(aField.Name + @": " + aField.Value.ToString());
                    else
                        Console.WriteLine(aField.Name + @": <No Value>");
                }
            }
        }

        /// <summary>
        /// Set default values on the presentation to inform the user no work item has been selected.
        /// </summary>
        private void UseDefaultValuesForWorkItemPresentation()
        {
            WorkItemTitle = "";
            WorkItemNumber = "";
            AssignedTo = "";
            WorkItemState = "";
            WorkItemTypeName = "";
        }
    }
}
